package com.akjava.gwt.bvhtools.client; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.akjava.bvh.client.BVH; import com.akjava.bvh.client.BVHMotion; import com.akjava.bvh.client.BVHNode; import com.akjava.bvh.client.BVHParser; import com.akjava.bvh.client.BVHParser.InvalidLineException; import com.akjava.bvh.client.BVHParser.ParserListener; import com.akjava.bvh.client.BVHWriter; import com.akjava.bvh.client.Channels; import com.akjava.bvh.client.NameAndChannel; import com.akjava.bvh.client.Vec3; import com.akjava.gwt.bvh.client.BoxData; import com.akjava.gwt.bvh.client.BoxDataParser; import com.akjava.gwt.bvh.client.poseframe.PoseEditorData; import com.akjava.gwt.bvh.client.poseframe.PoseFrameData; import com.akjava.gwt.bvh.client.threejs.AnimationBoneConverter; import com.akjava.gwt.bvh.client.threejs.BVHConverter; import com.akjava.gwt.bvhtools.client.file.BVHDataContainer; import com.akjava.gwt.bvhtools.client.file.BVHDataListener; import com.akjava.gwt.bvhtools.client.file.FileDataContainer; import com.akjava.gwt.bvhtools.client.file.TextDataContainer; import com.akjava.gwt.bvhtools.client.player.list.BVHFileWidget; import com.akjava.gwt.bvhtools.client.player.list.DataListCell; import com.akjava.gwt.bvhtools.client.player.list.DataListCell.ChangeSelectionListener; import com.akjava.gwt.bvhtools.client.player.list.DataListCell.DataListRenderer; import com.akjava.gwt.bvhtools.client.player.resources.Bundles; import com.akjava.gwt.bvhtools.client.tools.CalculateTool; import com.akjava.gwt.bvhtools.client.tools.MergeTool; import com.akjava.gwt.bvhtools.client.tools.MixTool; import com.akjava.gwt.bvhtools.client.tools.StripTool; import com.akjava.gwt.bvhtools.client.tools.TextTool; import com.akjava.gwt.bvhtools.client.tools.ThinTool; import com.akjava.gwt.html5.client.InputRangeWidget; import com.akjava.gwt.html5.client.download.HTML5Download; import com.akjava.gwt.html5.client.extra.HTML5Builder; import com.akjava.gwt.html5.client.file.File; import com.akjava.gwt.html5.client.file.FileUploadForm; import com.akjava.gwt.html5.client.file.FileUtils; import com.akjava.gwt.html5.client.file.ui.DropVerticalPanelBase; import com.akjava.gwt.lib.client.IStorageControler; import com.akjava.gwt.lib.client.LogUtils; import com.akjava.gwt.lib.client.StorageControler; import com.akjava.gwt.lib.client.StorageException; import com.akjava.gwt.three.client.gwt.animation.AnimationBone; import com.akjava.gwt.three.client.gwt.animation.AnimationBonesData; import com.akjava.gwt.three.client.gwt.materials.LineBasicMaterialParameter; import com.akjava.gwt.three.client.gwt.materials.MeshBasicMaterialParameter; import com.akjava.gwt.three.client.gwt.materials.MeshLambertMaterialParameter; import com.akjava.gwt.three.client.java.JClock; import com.akjava.gwt.three.client.java.ui.SimpleTabDemoEntryPoint; import com.akjava.gwt.three.client.java.utils.Object3DUtils; import com.akjava.gwt.three.client.js.THREE; import com.akjava.gwt.three.client.js.core.Geometry; import com.akjava.gwt.three.client.js.core.Object3D; import com.akjava.gwt.three.client.js.core.Projector; import com.akjava.gwt.three.client.js.lights.Light; import com.akjava.gwt.three.client.js.math.Euler; import com.akjava.gwt.three.client.js.math.Vector3; import com.akjava.gwt.three.client.js.objects.Line; import com.akjava.gwt.three.client.js.objects.Mesh; import com.akjava.gwt.three.client.js.renderers.WebGLRenderer; import com.akjava.lib.common.utils.Benchmark; import com.google.common.collect.Lists; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DropEvent; import com.google.gwt.event.dom.client.DropHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.resources.client.TextResource; import com.google.gwt.text.shared.Renderer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Frame; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.TabLayoutPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; /** * Entry point classes define <code>onModuleLoad()</code>. */ public class BVHTools extends SimpleTabDemoEntryPoint { private String version="5.1(for r66)"; public static DateTimeFormat dateFormat=DateTimeFormat.getFormat("yy/MM/dd HH:mm"); private static BVHTools bvhTools; public static BVHTools getInstance(){ return bvhTools; } final Projector projector=THREE.Projector(); @Override public void onMouseClick(ClickEvent event) { /* TODO future int x=event.getX(); int y=event.getY(); JsArray<Intersect> intersects=projector.gwtPickIntersects(event.getX(), event.getY(), screenWidth, screenHeight, camera,scene); for(int i=0;i<intersects.length();i++){ Intersect sect=intersects.get(i); break; } */ } @Override public void onMouseMove(MouseMoveEvent event) { if(mouseDown){ int diffX=event.getX()-mouseDownX; int diffY=event.getY()-mouseDownY; mouseDownX=event.getX(); mouseDownY=event.getY(); rotationRange.setValue(rotationRange.getValue()+diffY); rotationYRange.setValue(rotationYRange.getValue()+diffX); } } private int defaultZ=200; Map<String,Vector3> boneSizeMap=new HashMap<String,Vector3>(); private Object3D rootGroup,boneContainer,backgroundContainer; private Map<String,BoxData> boxDatas; private VerticalPanel datasPanel; private IStorageControler storageControler; @Override public void initializeOthers(WebGLRenderer renderer) { LogUtils.log("BVHTools version:"+version); loadDefaultBVH("pose.bvh"); //i forgot what is this?maybe for some slow network storageControler = new StorageControler(); bvhTools=this; cameraY=10; defaultZoom=5; renderer.setClearColor(0, 0);//use transparent canvas.setBackground(0xcccccc); //boxDatas=new BoxDataParser().parse(Bundles.INSTANCE.boxsize().getText()); boxDatas=new HashMap<String, BoxData>(); scene.add(THREE.AmbientLight(0x888888)); Light pointLight = THREE.PointLight(0xffffff); pointLight.setPosition(0, 10, 300); scene.add(pointLight); doLoad("14_08"); rootGroup=THREE.Object3D(); scene.add(rootGroup); backgroundContainer=THREE.Object3D(); rootGroup.add(backgroundContainer); Geometry geo=THREE.PlaneGeometry(100, 100,20,20); Mesh mesh=THREE.Mesh(geo, THREE.MeshBasicMaterial().color(0x666666).wireFrame(true).build()); //mesh.setPosition(0, -17, 0); mesh.getRotation().set(Math.toRadians(-90), 0, 0,Euler.XYZ); backgroundContainer.add(mesh); boneContainer=THREE.Object3D(); rootGroup.add(boneContainer); /* BVHParser parser=new BVHParser(); //String singleBvh=Bundles.INSTANCE.single_basic().getText(); //String singleBvh=Bundles.INSTANCE.twolink_n_rz().getText(); //String singleBvh=Bundles.INSTANCE.twolink_full().getText(); //String singleBvh=Bundles.INSTANCE.fourlink_branch().getText(); String singleBvh=Bundles.INSTANCE.twelve01().getText(); try { jointMap=new HashMap<String,Object3D>(); bvh = parser.parse(singleBvh); BVHNode node=bvh.getHiearchy(); root=THREE.Object3D(); scene.add(root); doLog(root,node); // //jointMap.get("Hips").setRotation(Math.toRadians(7.1338),Math.toRadians(-1.8542),Math.toRadians( -7.8190)); //doPose(bvh,"-0.3899 17.5076 7.8007 0 0 0 0 0 0 -21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -16 0 0 21 0 0 11 0 0 0 -8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); //doPose(bvh,"-0.3899 17.5076 7.8007 -7.8190 -1.8542 7.1338 0.0000 0.0000 0.0000 -20.0095 -34.8717 23.1818 0.0543 -1.5040 -4.1368 -5.1851 39.6153 -34.2618 0.1274 2.3012 6.3387 0.0000 0.0000 0.0000 27.9815 23.6282 8.6217 -0.0094 -0.6245 1.7162 0.4741 -16.6281 -18.3131 -0.0041 -0.4123 1.1330 4.5929 -0.1445 3.0131 1.7537 0.3513 -8.5234 -0.7284 -0.1282 -10.7842 -14.7495 -15.2891 1.4491 15.1151 -23.2999 16.3175 5.0944 -11.3477 8.3590 -0.0000 -0.0000 0.0000 -91.7499 11.2503 9.6316 11.7870 -19.4845 -2.0307 -0.0000 -0.0000 23.6415 17.7243 -7.2146 -2.2985 -7.1250 0.0000 -0.0000 -6.6264 22.4256 3.6210 -0.0000 -0.0000 0.0000 92.9366 -10.7837 -16.0742 -9.0830 15.2927 -1.2219 0.0000 0.0000 58.8395 3.1909 -29.5170 -1.5733 7.1250 -0.0000 -0.0000 36.2824 -55.5617 -10.3909"); //doPose(bvh,"-0.5011 17.6282 7.6163 -6.2586 -15.2051 5.4723 0.0000 0.0000 0.0000 -21.3981 -26.0192 22.4790 0.0292 -1.1029 -3.0320 -3.3535 38.5451 -41.4272 0.6169 5.0265 13.9840 0.0000 0.0000 0.0000 24.7397 22.1958 5.0034 -0.0966 -2.0046 5.5183 -0.3873 -3.4522 -13.5373 -0.2228 3.0387 -8.3865 3.1625 -2.9263 2.2948 2.9237 -3.5238 -7.9690 1.7270 -1.8496 -9.7328 3.3763 2.5058 -7.4595 13.0244 0.5160 17.4961 3.6704 1.4696 6.5682 -0.0000 0.0000 0.0000 -42.7751 -56.6315 -8.6834 50.4538 -53.1769 -26.5370 -0.0000 0.0000 -77.6575 14.7878 7.4808 1.9684 -7.1250 0.0000 -0.0000 -10.2345 37.5343 1.9047 -0.0000 0.0000 0.0000 76.3877 59.4476 93.5538 -141.2974 47.2822 -102.5201 0.0000 -0.0000 -31.1956 -12.8820 -58.8974 11.0797 7.1250 -0.0000 -0.0000 91.0580 -76.5215 -77.2227"); doPose(bvh,bvh.getMotion().getMotions().get(0)); Matrix4 mx=THREE.Matrix4(); mx.setRotationFromEuler(THREE.Vector3(Math.toRadians(23.1818),Math.toRadians(-34.8717),Math.toRadians(-20.0095)), "ZYX"); Vector3 rot=THREE.Vector3(0, 0, 0); rot.setRotationFromMatrix(mx); double x=Math.toDegrees(rot.getX()); double y=Math.toDegrees(rot.getY()); double z=Math.toDegrees(rot.getZ()); GWT.log(x+","+y+","+z); //jointMap.get("LeftUpLeg").setRotation(rot.getX(), rot.getY(), rot.getZ()); //jointMap.get("LeftUpLeg").setRotation(Math.toRadians(23.1818),Math.toRadians(-34.8717),Math.toRadians(-20.0095)); //jointMap.get("RightUpLeg").getRotation(Math.toRadians(23.1818),Math.toRadians(-34.8717),Math.toRadians(-20.0095)); } catch (InvalidLineException e) { log(e.getMessage()); e.printStackTrace(); } */ // ctime=System.currentTimeMillis(); tabPanel.addSelectionHandler(new SelectionHandler<Integer>() { @Override public void onSelection(SelectionEvent<Integer> event) { int selection=event.getSelectedItem(); if(selection==0){ stats.setVisible(true); showControl(); popupPanel.setVisible(true); }else{ stats.setVisible(false); hideControl(); popupPanel.setVisible(false); } } }); toolsPanel = new TabLayoutPanel(24,Unit.PX); tabPanel.add(toolsPanel,"Tools"); //data is not compatible anymore //createDataPanel(); //no need experimental //createExperimentalPanel(); new MergeTool(createTabVerticalPanel("Merge")); new ThinTool(createTabVerticalPanel("ThinOut")); new StripTool(createTabVerticalPanel("Strip")); new MixTool(createTabVerticalPanel("Mix")); new CalculateTool(createTabVerticalPanel("Calculate")); new TextTool(createTabVerticalPanel("Text")); updateDatasPanel(); } private void createExperimentalPanel(){ VerticalPanel expRoot=new VerticalPanel(); tabPanel.add(expRoot,"Experimental"); Frame doc1=new Frame("pose_help.html"); doc1.setSize("500px", "200px"); Button bt1=new Button("Open Pose Editor"); bt1.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { Window.open("pose.html", "posetool", null); } }); expRoot.add(doc1); expRoot.add(bt1); Frame doc=new Frame("weight_help.html"); doc.setSize("500px", "200px"); Button bt=new Button("Open Model Weight Tool"); bt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { Window.open("weight.html", "weighttool", null); } }); expRoot.add(doc); expRoot.add(bt); } private void createDataPanel(){ VerticalPanel datasRoot=new VerticalPanel(); tabPanel.add(datasRoot,"Datas"); datasPanel = new VerticalPanel(); //datasPanel.setStyleName("debug"); ScrollPanel scroll=new ScrollPanel(datasPanel); scroll.setSize("550px", "400px"); HorizontalPanel control=new HorizontalPanel(); datasRoot.add(control); Button load=new Button("Load Checked Datas"); control.add(load); load.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { List<BVHDataContainer> datas=new ArrayList<BVHDataContainer>(); int size=datasPanel.getWidgetCount(); for(int i=0;i<size;i++){ Widget w=datasPanel.getWidget(i); if(w instanceof DataPanel){ DataPanel panel=(DataPanel)w; if(panel.isChecked()){ TextDataContainer dataContainer=new TextDataContainer(panel.getName(), convertPoseEditorDataToBVH(panel.getPoseEditorData(),bvhForData)); datas.add(dataContainer); } } } addBVHDatas(datas); } }); Button check=new Button("Check All"); control.add(check); check.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int size=datasPanel.getWidgetCount(); for(int i=0;i<size;i++){ Widget w=datasPanel.getWidget(i); if(w instanceof DataPanel){ DataPanel panel=(DataPanel)w; panel.setChecked(true); } } } }); Button uncheck=new Button("Uncheck All"); control.add(uncheck); uncheck.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int size=datasPanel.getWidgetCount(); for(int i=0;i<size;i++){ Widget w=datasPanel.getWidget(i); if(w instanceof DataPanel){ DataPanel panel=(DataPanel)w; panel.setChecked(false); } } } }); Button updateList=new Button("Update List"); control.add(updateList); updateList.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { updateDatasPanel(); } }); datasRoot.add(scroll); } private void updateDatasPanel(){ if(datasPanel==null){ return; } try{ datasPanel.clear(); int index=storageControler.getValue(PoseEditorData.KEY_INDEX, 0); for(int i=index;i>=0;i--){ String b64=storageControler.getValue(PoseEditorData.KEY_IMAGE+i,null); String json=storageControler.getValue(PoseEditorData.KEY_DATA+i,null); String head=storageControler.getValue(PoseEditorData.KEY_HEAD+i,null); if(b64!=null && json!=null){ DataPanel dp=new DataPanel(i,head,b64,json); //dp.setSize("200px", "200px"); datasPanel.add(dp); } } }catch (StorageException e) { Window.alert("faild getValue:"+e.getMessage()); } } public class DataPanel extends HorizontalPanel{ private int index; private String name; private long cdate; private String json; private CheckBox check; public DataPanel(final int ind,String head,String base64, String text){ json=text; this.index=ind; Image img=new Image(); img.setUrl(base64); String name_cdate[]=head.split("\t"); name=name_cdate[0]; cdate=(long)(Double.parseDouble(name_cdate[1])); String dlabel=dateFormat.format(new Date(cdate)); add(new Label(dlabel)); add(img); final Label nameLabel=new Label(name); nameLabel.setWidth("160px"); add(nameLabel); check = new CheckBox(); add(check); Button loadBt=new Button("Load"); add(loadBt); loadBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PoseEditorData ped=getPoseEditorData(); if(ped!=null){ doLoadPoseEditorData(ped); }else{ //TODO error catch Window.alert("load faild"); } } }); } public void setChecked(boolean bool){ check.setValue(bool); } public PoseEditorData getPoseEditorData(){ PoseEditorData ped=PoseEditorData.readData(json); if(ped!=null){ ped.setFileId(index); } return ped; } public boolean isChecked(){ return check.getValue(); } public String getJson(){ return json; } public String getName(){ return name; } protected void doLoadPoseEditorData(PoseEditorData ped) { //parseBVH(); TextDataContainer dataContainer=new TextDataContainer(name, convertPoseEditorDataToBVH(ped,bvhForData)); addBVHData(dataContainer); } } private VerticalPanel createTabVerticalPanel(String name){ VerticalPanel panel=new VerticalPanel(); toolsPanel.add(panel,name); return panel; } private void doRotation(Object3D target,String lastOrder){ //log(target.getName()+",order="+lastOrder+" "+ThreeLog.get(GWTThreeUtils.radiantToDegree(target.getRotation()))); target.getRotation().setOrder(lastOrder); /* Matrix4 mx=THREE.Matrix4(); mx.setRotationFromEuler(vec, lastOrder); vec.setRotationFromMatrix(mx);//in this here,miss rotation because of over 90? */ } /* private void doPose(BVH bvh,String line){ String[] tmp=line.split(" "); double[] vs=BVHParser.toDouble(tmp); Object3D oldTarget=null; String lastOrder=null; for(int i=0;i<vs.length;i++){ NameAndChannel nchannel=bvh.getNameAndChannels().get(i); lastOrder=nchannel.getOrder(); Object3D target=jointMap.get(nchannel.getName()); switch(nchannel.getChannel()){ case Channels.XROTATION: target.getRotation().setX(Math.toRadians(vs[i])); break; case Channels.YROTATION: target.getRotation().setY(Math.toRadians(vs[i])); break; case Channels.ZROTATION: target.getRotation().setZ(Math.toRadians(vs[i])); break; } if(oldTarget!=null && oldTarget!=target){ doZYX(oldTarget,lastOrder); } oldTarget=target; } doZYX(oldTarget,lastOrder);//do last one }*/ public static String convertPoseEditorDataToBVH(PoseEditorData ped,BVH bvh){ AnimationBoneConverter boneConverter=new AnimationBoneConverter(); JsArray<AnimationBone> bones=boneConverter.convertJsonBone(bvh); AnimationBonesData ab=new AnimationBonesData(bones, null); ped.updateMatrix(ab);//current-bone BVH exportBVH=new BVH(); BVHConverter converter=new BVHConverter(); BVHNode node=converter.convertBVHNode(bones); exportBVH.setHiearchy(node); converter.setChannels(node,0,"XYZ"); //TODO support other order BVHMotion motion=new BVHMotion(); motion.setFrameTime(.25); for(PoseFrameData pose:ped.getPoseFrameDatas()){ double[] values=converter.angleAndMatrixsToMotion(pose.getAngleAndMatrixs(),BVHConverter.ROOT_POSITION_ROTATE_ONLY,"XYZ"); motion.add(values); } motion.setFrames(motion.getMotions().size());// exportBVH.setMotion(motion); //log("frames:"+exportBVH.getFrames()); BVHWriter writer=new BVHWriter(); String bvhText=writer.writeToString(exportBVH); return bvhText; } private void doPose(BVH bvh,double[] vs){ Object3D oldTarget=null; String lastOrder=null; for(int i=0;i<vs.length;i++){ NameAndChannel nchannel=bvh.getNameAndChannels().get(i); lastOrder=nchannel.getOrder(); Object3D target=jointMap.get(nchannel.getName()); switch(nchannel.getChannel()){ case Channels.XROTATION: target.getRotation().setX(Math.toRadians(vs[i])); break; case Channels.YROTATION: target.getRotation().setY(Math.toRadians(vs[i])); break; case Channels.ZROTATION: target.getRotation().setZ(Math.toRadians(vs[i])); break; case Channels.XPOSITION: if(translatePosition.getValue()){ target.getPosition().setX(vs[i]); }else{ target.getPosition().setX(0); } break; case Channels.YPOSITION: if(translatePosition.getValue()){ target.getPosition().setY(vs[i]); }else{ target.getPosition().setY(0); } break; case Channels.ZPOSITION: if(translatePosition.getValue()){ target.getPosition().setZ(vs[i]); }else{ target.getPosition().setZ(0); } break; } if(oldTarget!=null && oldTarget!=target){ doRotation(oldTarget,lastOrder); } oldTarget=target; } doRotation(oldTarget,lastOrder);//do last one } private Map<String,Object3D> jointMap; public Line createLine(Vec3 from,Vec3 to){ Geometry lineG = THREE.Geometry(); lineG.vertices().push(THREE.Vector3(from.getX(), from.getY(), from.getY())); lineG.vertices().push(THREE.Vector3(to.getX(), to.getY(), to.getZ())); Line line=THREE.Line(lineG, THREE.LineBasicMaterial(LineBasicMaterialParameter.create().color(0))); return line; } private List<Object3D> bodyMeshs=new ArrayList<Object3D>(); double baseBoneSize=0.4; String tmp=""; public void doJoint(Object3D parent,BVHNode pNode,BVHNode node){ if(pNode!=null){ LogUtils.log(pNode.getName()+","+node.getName()); }else{ LogUtils.log(null+","+node.getName()); } GWT.log(node.getName()+","+node.getOffset()+",endsite:"+node.getEndSite()); GWT.log(node.getChannels().toString()); Object3D group=THREE.Object3D(); Mesh mesh=THREE.Mesh(THREE.CubeGeometry(baseBoneSize,baseBoneSize,baseBoneSize), THREE.MeshLambertMaterial(MeshLambertMaterialParameter.create().color(0x00ff00))); group.add(mesh); mesh.setName(node.getName()); group.setName(node.getName()); //initial position group.setPosition(THREE.Vector3(node.getOffset().getX(), node.getOffset().getY(), node.getOffset().getZ())); jointMap.put(node.getName(), group); //create half Vector3 half=group.getPosition().clone(); if(half.getX()!=0 || half.getY()!=0 || half.getY()!=0){ half.divideScalar(2); //Mesh hmesh=THREE.Mesh(THREE.CubeGeometry(.2,.2,.2), THREE.MeshLambertMaterial().color(0xffffff).build()); Mesh halfMesh=THREE.Mesh(THREE.CylinderGeometry(baseBoneSize/4,baseBoneSize/4,baseBoneSize/2,6), THREE.MeshLambertMaterial(MeshLambertMaterialParameter.create().color(0xffffff))); halfMesh.setPosition(half); if(pNode!=null){ parent.add(halfMesh); bodyMeshs.add(halfMesh); } if(pNode!=null){ tmp+=pNode.getName()+",1,1,1\n"; //this is supported-bone structor. BoxData data=boxDatas.get(pNode.getName());// if(data!=null){ halfMesh.setScale(data.getScaleX(), data.getScaleY(), data.getScaleZ()); halfMesh.getRotation().setZ(Math.toRadians(data.getRotateZ())); } } } //line Line lineMesh=createLine(new Vec3(),node.getOffset()); if(pNode!=null){ parent.add(lineMesh); } if(node.getEndSite()!=null){ Mesh end=THREE.Mesh(THREE.CubeGeometry(baseBoneSize/4,baseBoneSize/4,baseBoneSize/4), THREE.MeshBasicMaterial(MeshBasicMaterialParameter.create().color(0x008800))); end.setPosition(THREE.Vector3(node.getEndSite().getX(), node.getEndSite().getY(), node.getEndSite().getZ())); group.add(end); Geometry lineG = THREE.Geometry(); lineG.vertices().push(THREE.Vector3(0, 0, 0)); lineG.vertices().push(THREE.Vector3(node.getEndSite().getX(), node.getEndSite().getY(), node.getEndSite().getZ())); Line line=THREE.Line(lineG, THREE.LineBasicMaterial(LineBasicMaterialParameter.create().color(0))); group.add(line); Vector3 half2=end.getPosition().clone(); if(half2.getX()!=0 || half2.getY()!=0 || half2.getY()!=0){ half2.divideScalar(2); //Mesh hmesh=THREE.Mesh(THREE.CubeGeometry(.1,.1,.1), THREE.MeshLambertMaterial().color(0xffffff).build()); Mesh hmesh=THREE.Mesh(THREE.CylinderGeometry(baseBoneSize/4,baseBoneSize/4,baseBoneSize/2,6), THREE.MeshLambertMaterial(MeshLambertMaterialParameter.create().color(0xffffff))); hmesh.setPosition(half2); group.add(hmesh); tmp+=node.getName()+",1,1,1\n"; //this is special treatment for bone. BoxData data=boxDatas.get(node.getName()); if(data!=null){ hmesh.setScale(data.getScaleX(), data.getScaleY(), data.getScaleZ()); } if(node.getName().equals("Head")){//why need this? // hmesh.getPosition().setZ(hmesh.getPosition().getZ()+0.5); } bodyMeshs.add(hmesh); } } parent.add(group); List<BVHNode> joints=node.getJoints(); if(joints!=null){ for(BVHNode joint:joints){ doJoint(group,node,joint); } } } private Label loadingLabel=new Label(); private CheckBox translatePosition; private InputRangeWidget positionYRange; private InputRangeWidget meshScaleX; private InputRangeWidget meshScaleY; private InputRangeWidget meshScaleZ; private InputRangeWidget positionX; private InputRangeWidget positionY; private InputRangeWidget positionZ; private PopupPanel bottomPanel; protected boolean playing; private InputRangeWidget positionXRange; private InputRangeWidget positionZRange; private CheckBox drawBackground; private void loadBVH(String path){ Benchmark.start("load"); RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(path)); loadingLabel.setText("loading-data"); try { builder.sendRequest(null, new RequestCallback() { @Override public void onResponseReceived(Request request, Response response) { String bvhText=response.getText(); //log("loaded:"+Benchmark.end("load")); //useless spend allmost time with request and spliting. parseBVH(bvhText); loadingLabel.setText(""); } @Override public void onError(Request request, Throwable exception) { Window.alert("load faild:"); } }); } catch (RequestException e) { LogUtils.log(e.getMessage()); e.printStackTrace(); } } private void setEmptyBone(){ if(boneRoot!=null){ boneContainer.remove(boneRoot); } boneRoot=null; bvh=null; } //TODO can choose in preference private BVH bvhForData; private void loadDefaultBVH(final String path){ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(path)); try { builder.sendRequest(null, new RequestCallback() { @Override public void onResponseReceived(Request request, Response response) { String bvhText=response.getText(); BVHParser parser=new BVHParser(); try { bvhForData= parser.parse(bvhText); } catch (InvalidLineException e) { LogUtils.log("invalid bvh:"+e.getMessage()); e.printStackTrace(); } } @Override public void onError(Request request, Throwable exception) { Window.alert("load faild:"+path); } }); } catch (RequestException e) { LogUtils.log(e.getMessage()); e.printStackTrace(); } } private void setBVH(BVH bv){ bvh=bv; bvh.setSkips(skipFrames); BVHNode node=bvh.getHiearchy(); if(boneRoot!=null){ boneContainer.remove(boneRoot); } boneRoot=THREE.Object3D(); boneContainer.add(boneRoot); //possible bone root is not 0 boneRoot.setPosition(node.getOffset().getX(),node.getOffset().getY(),node.getOffset().getZ()); doJoint(boneRoot,null,node); //GWT.log(tmp); int poseIndex=0; GWT.log("f-size:"+bvh.getFrames()); if(ignoreFirst.getValue() && bvh.getFrames()>1){ poseIndex=1; } clock.update(); updatePoseIndex(poseIndex); doPose(bvh,bvh.getFrameAt(poseIndex)); currentFrameRange.setMax(bvh.getFrames()-1); } private void parseBVH(String bvhText){ final BVHParser parser=new BVHParser(); jointMap=new HashMap<String,Object3D>(); parser.parseAsync(bvhText, new ParserListener() { @Override public void onSuccess(BVH bv) { setBVH(bv); } @Override public void onFaild(String message) { LogUtils.log(message); } }); } /* timer style * parser.initialize(); bvhText=bvhText.replace("\r", ""); final String lines[]=bvhText.split("\n"); final int pLine=lines.length/20; Timer timer=new Timer(){ int index=0; boolean parsing; @Override public synchronized void run() { if(parsing){ return; } parsing=true; loadingLabel.setText(index+"/"+lines.length); GWT.log("called:"+index+","+pLine); try { parser.parseLines(lines, index, index+pLine); if(index>=lines.length){ //done bvh=parser.getBvh(); BVHNode node=bvh.getHiearchy(); if(root!=null){ scene.remove(root); } root=THREE.Object3D(); scene.add(root); doLog(root,node); doPose(bvh,bvh.getMotion().getMotions().get(0)); poseIndex=0; cancel(); }else{ index+=pLine; } } catch (InvalidLineException e) { log(e.getMessage()); } parsing=false; } }; timer.scheduleRepeating(20); */ private long getFrameTime(int index){ long time=(long) (bvh.getFrameTime()*index*1000); return time; } private double getPlaySpeed(){ String v=speedBox.getItemText(speedBox.getSelectedIndex()); double r=1; try{ r=Double.parseDouble(v.substring(2)); }catch(Exception e){} return r; } private double playSpeed=1; private void createBottomPanel(){ bottomPanel = new PopupPanel(); bottomPanel.setVisible(true); bottomPanel.setSize("650px", "40px"); VerticalPanel main=new VerticalPanel(); bottomPanel.add(main); bottomPanel.show(); HorizontalPanel upperPanel=new HorizontalPanel(); upperPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); main.add(upperPanel); upperPanel.add(new Label("Speed")); speedBox = new ListBox(); speedBox.addItem("x 0.25"); speedBox.addItem("x 0.5"); speedBox.addItem("x 1"); speedBox.addItem("x 2"); speedBox.addItem("x 4"); speedBox.addItem("x 10"); speedBox.setSelectedIndex(2); speedBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { playSpeed=getPlaySpeed(); } }); upperPanel.add(speedBox); abLoopCheck = new CheckBox("A/B Loop"); upperPanel.add(abLoopCheck); final Button asA=new Button("A:"); asA.setWidth("60px"); upperPanel.add(asA); asA.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { aFrame=currentFrameRange.getValue(); asA.setText("A:"+(aFrame+1)); } }); final Button asB=new Button("B:"); asB.setWidth("60px"); upperPanel.add(asB); asB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { bFrame=currentFrameRange.getValue(); asB.setText("B:"+(bFrame+1)); } }); upperPanel.add(new Label("Skip every frame:")); final TextBox skipFrameBox=new TextBox(); skipFrameBox.setWidth("40px"); upperPanel.add(skipFrameBox); Button updateSkipBt=new Button("Update skips"); upperPanel.add(updateSkipBt); updateSkipBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { String v=skipFrameBox.getValue(); int sp=0; try{ sp=Integer.parseInt(v); }catch(Exception e){ } setBvhSkips(sp); } }); HorizontalPanel pPanel=new HorizontalPanel(); main.add(pPanel); pPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); playing=true; final Button playButton=new Button("Play"); playButton.setEnabled(false); final Button stopButton=new Button("Stop"); playButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { clock.update(); //ctime=System.currentTimeMillis()-getFrameTime(); playing=true; playButton.setEnabled(false); stopButton.setEnabled(true); } }); pPanel.add(playButton); stopButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { playing=false; playButton.setEnabled(true); stopButton.setEnabled(false); } }); pPanel.add(stopButton); final Button prevButton=new Button("Prev"); prevButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int c=currentFrameRange.getValue(); c--; /* if(c==0 && ignoreFirst.getValue()){ c=1; }*/ if(c<0){ c=0; } currentFrameRange.setValue(c); updatePoseIndex(currentFrameRange.getValue()); } }); pPanel.add(prevButton); final Button nextButton=new Button("Next"); nextButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { int c=currentFrameRange.getValue(); c++; if(c>=bvh.getFrames()){ c=bvh.getFrames()-1; } currentFrameRange.setValue(c); updatePoseIndex(currentFrameRange.getValue()); } }); pPanel.add(nextButton); currentFrameRange = InputRangeWidget.createInputRange(0,1000,0); currentFrameRange.setWidth("420px"); pPanel.add(currentFrameRange); currentFrameRange.addMouseUpHandler(new MouseUpHandler() { @Override public void onMouseUp(MouseUpEvent event) { updatePoseIndex(currentFrameRange.getValue()); } }); currentFrameLabel = new Label(); pPanel.add(currentFrameLabel); super.leftBottom(bottomPanel); } private int aFrame; private int bFrame; private int skipFrames; private CheckBox drawMesh; private void setBvhSkips(int skips){ //TODO //set global for newload skipFrames=skips; //set current bvh bvh.setSkips(skips); updatePoseIndex(0); currentFrameRange.setMax(bvh.getFrames()-1); //update labels } private JsArray<File> lastSelectedFiles; private BVHDataListener bvhDataListener; @Override public void createControl(DropVerticalPanelBase parent) { bvhDataListener=new BVHDataListener() { @Override public void dataLoaded(String text) { parseBVH(text); } }; parent.add(loadingLabel); parent.add(new Label("Load BVH File")); final FileUploadForm file=new FileUploadForm(); file.setAccept(".bvh"); file.getFileUpload().setHeight("50px"); file.getFileUpload().getElement().setAttribute("multiple", "multiple"); parent.addDropHandler(new DropHandler() { @Override public void onDrop(DropEvent event) { event.preventDefault(); //final FileReader reader=FileReader.createFileReader(); lastSelectedFiles=FileUtils.transferToFile(event.getNativeEvent()); FileDataContainer firstOne=null; for(int i=0;i<lastSelectedFiles.length();i++){ FileDataContainer container=new FileDataContainer(lastSelectedFiles.get(i)); if(i==0){ firstOne=container; } bvhFileList.add(container); } dataListCell.setDatas(bvhFileList); dataListCell.setSelection(firstOne); file.reset(); } }); file.getFileUpload().addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { //Benchmark.start("load"); lastSelectedFiles = FileUtils.toFile(event.getNativeEvent()); FileDataContainer firstOne=null; for(int i=0;i<lastSelectedFiles.length();i++){ FileDataContainer container=new FileDataContainer(lastSelectedFiles.get(i)); if(i==0){ firstOne=container; } bvhFileList.add(container); } dataListCell.setDatas(bvhFileList); dataListCell.setSelection(firstOne); file.reset(); } }); parent.add(file); HorizontalPanel fileControl=new HorizontalPanel(); fileControl.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); parent.add(fileControl); Button prevBt=new Button("Prev"); prevBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if(bvhFileList.size()==0){ return; } BVHDataContainer file=dataListCell.getSelection(); int index=bvhFileList.indexOf(file); index--; if(index<0){ index=bvhFileList.size()-1; } dataListCell.setSelection(bvhFileList.get(index)); } }); fileControl.add(prevBt); Button nextBt=new Button("Next"); nextBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { doNextMotion(); } }); fileControl.add(nextBt); fileControl.add(new Label("Auto Play")); loopTime = new ListBox(); loopTime.addItem("None"); loopTime.addItem("1"); loopTime.addItem("3"); loopTime.addItem("10"); loopTime.setSelectedIndex(0); fileControl.add(loopTime); file.setStylePrimaryName("fileborder"); /* meshScaleX = new HTML5InputRange(0,150,3); parent.add(HTML5Builder.createRangeLabel("Scale-x", meshScaleX)); parent.add(meshScaleX); meshScaleY = new HTML5InputRange(0,150,3); parent.add(HTML5Builder.createRangeLabel("Scale-y", meshScaleY)); parent.add(meshScaleY); meshScaleZ = new HTML5InputRange(0,150,3); parent.add(HTML5Builder.createRangeLabel("Scale-z", meshScaleZ)); parent.add(meshScaleZ); positionX = new HTML5InputRange(-150,150,0); parent.add(HTML5Builder.createRangeLabel("Position-x", positionX)); parent.add(positionX); positionY = new HTML5InputRange(-150,150,0); parent.add(HTML5Builder.createRangeLabel("Position-y", positionY)); parent.add(positionY); positionZ = new HTML5InputRange(-150,150,0); parent.add(HTML5Builder.createRangeLabel("Position-z", positionZ)); parent.add(positionZ); */ dataListCell = new DataListCell<BVHDataContainer>(new DataListRenderer<BVHDataContainer>(){ @Override public Widget createWidget(BVHDataContainer data,DataListCell<BVHDataContainer> dataList) { return new BVHFileWidget(data,dataList); }}); dataListCell.setHeight("60px"); parent.add(dataListCell); dataListCell.setListener(new ChangeSelectionListener<BVHDataContainer>() { @Override public void onChangeSelection(BVHDataContainer data) { /* final FileReader reader=FileReader.createFileReader(); reader.setOnLoad(new FileHandler() { @Override public void onLoad() { parseBVH(reader.getResultAsString()); } }); reader.readAsText(data,"utf-8"); */ data.readText(bvhDataListener); } }); HorizontalPanel dataControls=new HorizontalPanel(); parent.add(dataControls); Button remove=new Button("Remove"); remove.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if(bvhFileList.size()==0){ return; } BVHDataContainer file=dataListCell.getSelection(); int index=bvhFileList.indexOf(file); bvhFileList.remove(file); if(index>=bvhFileList.size()){ index=0; } dataListCell.setDatas(bvhFileList); if(bvhFileList.size()!=0){ dataListCell.setSelection(bvhFileList.get(index)); }else{ setEmptyBone(); } } }); dataControls.add(remove); Button removeAll=new Button("Remove All"); removeAll.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if(bvhFileList.size()==0){ return; } bvhFileList.clear(); dataListCell.setDatas(bvhFileList); setEmptyBone(); } }); dataControls.add(removeAll); Button reload=new Button("Reload"); reload.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { doReload(); } }); dataControls.add(reload); drawMesh = new CheckBox("Draw Body Mesh"); parent.add(drawMesh); drawMesh.setValue(true); drawMesh.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { doChangeVisibleBodyMesh(); } }); drawBackground = new CheckBox("Draw Background"); parent.add(drawBackground); drawBackground.setValue(true); translatePosition = new CheckBox("Translate Position"); parent.add(translatePosition); translatePosition.setValue(true); translatePosition.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { updatePoseIndex(currentFrameRange.getValue()); } }); ignoreFirst = new CheckBox("Ignore First Frame(Usually Pose)"); ignoreFirst.setValue(false);//only cmu parent.add(ignoreFirst); HorizontalPanel h1=new HorizontalPanel(); rotationRange = InputRangeWidget.createInputRange(-180,180,0); parent.add(HTML5Builder.createRangeLabel("X-Rotate:", rotationRange)); parent.add(h1); h1.add(rotationRange); Button reset=new Button("Reset"); reset.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { rotationRange.setValue(0); } }); h1.add(reset); HorizontalPanel h2=new HorizontalPanel(); rotationYRange = InputRangeWidget.createInputRange(-180,180,0); parent.add(HTML5Builder.createRangeLabel("Y-Rotate:", rotationYRange)); parent.add(h2); h2.add(rotationYRange); Button reset2=new Button("Reset"); reset2.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { rotationYRange.setValue(0); } }); h2.add(reset2); HorizontalPanel h3=new HorizontalPanel(); rotationZRange = InputRangeWidget.createInputRange(-180,180,0); parent.add(HTML5Builder.createRangeLabel("Z-Rotate:", rotationZRange)); parent.add(h3); h3.add(rotationZRange); Button reset3=new Button("Reset"); reset3.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { rotationZRange.setValue(0); } }); h3.add(reset3); HorizontalPanel h4=new HorizontalPanel(); positionXRange = InputRangeWidget.createInputRange(-50,50,0); parent.add(HTML5Builder.createRangeLabel("X-Position:", positionXRange)); parent.add(h4); h4.add(positionXRange); Button reset4=new Button("Reset"); reset4.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { positionXRange.setValue(0); } }); h4.add(reset4); HorizontalPanel h5=new HorizontalPanel(); positionYRange = InputRangeWidget.createInputRange(-50,50,0); parent.add(HTML5Builder.createRangeLabel("Y-Position:", positionYRange)); parent.add(h5); h5.add(positionYRange); Button reset5=new Button("Reset"); reset5.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { positionYRange.setValue(0); } }); h5.add(reset5); HorizontalPanel h6=new HorizontalPanel(); positionZRange = InputRangeWidget.createInputRange(-50,50,0); parent.add(HTML5Builder.createRangeLabel("Z-Position:", positionZRange)); parent.add(h6); h6.add(positionZRange); Button reset6=new Button("Reset"); reset6.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { positionZRange.setValue(0); } }); h6.add(reset6); /* Button launchPose=new Button("Launch Pose Editor"); parent.add(launchPose); launchPose.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { Window.open("pose.html", "posetool", null); } }); */ List<Double> boneSizes=Lists.newArrayList(0.1,0.2,0.4,0.8,1.0,2.0); ValueListBox<Double> boneSizeListBox=new ValueListBox<Double>(new Renderer<Double>() { @Override public String render(Double object) { return String.valueOf(object); } @Override public void render(Double object, Appendable appendable) throws IOException { // TODO Auto-generated method stub } }); boneSizeListBox.setValue(baseBoneSize); boneSizeListBox.setAcceptableValues(boneSizes); boneSizeListBox.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { baseBoneSize=event.getValue(); setBVH(bvh);//re-set } }); HorizontalPanel jointSizesPanel=new HorizontalPanel(); jointSizesPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); jointSizesPanel.add(new Label("Joint-Size")); jointSizesPanel.add(boneSizeListBox); parent.add(jointSizesPanel); List<TextResource> presets=Lists.newArrayList(null,Bundles.INSTANCE.standard_cmu(),Bundles.INSTANCE.small_cmu()); ValueListBox<TextResource> presetBox=new ValueListBox<TextResource>(new Renderer<TextResource>() { @Override public String render(TextResource object) { if(object==null){ return "no use"; }else{ return object.getName(); } //return null; } @Override public void render(TextResource object, Appendable appendable) throws IOException { // TODO Auto-generated method stub } }); presetBox.addValueChangeHandler(new ValueChangeHandler<TextResource>() { @Override public void onValueChange(ValueChangeEvent<TextResource> event) { if(event.getValue()==null){ boxDatas=new HashMap<String, BoxData>(); }else{ boxDatas=new BoxDataParser().parse(event.getValue().getText()); } setBVH(bvh);//re-set } }); presetBox.setAcceptableValues(presets); HorizontalPanel presetPanel=new HorizontalPanel(); presetPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); presetPanel.add(new Label("Joint-Preset")); presetPanel.add(presetBox); parent.add(presetPanel); HorizontalPanel screenshotPanel=new HorizontalPanel(); screenshotPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); parent.add(screenshotPanel); screenshotContainer = new HorizontalPanel(); Button screenShot=new Button("Screenshot",new ClickHandler() { @Override public void onClick(ClickEvent event) { reserveScreenShot=true; } }); screenshotPanel.add(screenShot); screenshotPanel.add(screenshotContainer); createBottomPanel(); showControl(); } private boolean reserveScreenShot; public class TextResourceAndName{ TextResource resource; public TextResource getResource() { return resource; } public void setResource(TextResource resource) { this.resource = resource; } public String getName() { return name; } public void setName(String name) { this.name = name; } String name; } protected void doReload() { LogUtils.log(lastSelectedFiles); if(lastSelectedFiles==null){ return; } //bvhFileList.clear(); FileDataContainer firstOne=null; for(int i=0;i<lastSelectedFiles.length();i++){ FileDataContainer container=new FileDataContainer(lastSelectedFiles.get(i)); if(i==0){ firstOne=container; } bvhFileList.add(container); } dataListCell.setDatas(bvhFileList); dataListCell.setSelection(firstOne); } protected void doChangeVisibleBodyMesh() { for(Object3D object:bodyMeshs){ object.setVisible(drawMesh.getValue()); } } private void doNextMotion(){ if(bvhFileList.size()==0){ return; } BVHDataContainer file=dataListCell.getSelection(); int index=bvhFileList.indexOf(file); index++; if(index>bvhFileList.size()-1){ index=0; } dataListCell.setSelection(bvhFileList.get(index)); } protected void doLoad(String itemText) { String[] g_n=itemText.split("_"); loadBVH("bvhs/"+g_n[0]+"/"+itemText+".bvh"); } private InputRangeWidget rotationRange; private InputRangeWidget rotationYRange; private InputRangeWidget rotationZRange; Object3D boneRoot; private BVH bvh; private CheckBox ignoreFirst; //private long ctime; private InputRangeWidget currentFrameRange; private Label currentFrameLabel; //private int poseIndex; private void updatePoseIndex(int index){ if(index>=bvh.getFrames()){ if(bvh.getFrames()!=1){//1 frame pose usually happen LogUtils.log("invalid frame at:"+index+" of "+bvh.getFrames()); } return; } //poseIndex=index; currentFrameRange.setValue(index); currentFrameLabel.setText((index+1)+"/"+bvh.getFrames()); doPose(bvh,bvh.getFrameAt(index)); } JClock clock=new JClock(); private List<BVHDataContainer> bvhFileList=new ArrayList<BVHDataContainer>(); //private CellList<File> bvhCellList; //private SingleSelectionModel<File> fileSelectionModel; private DataListCell<BVHDataContainer> dataListCell; private int currentLoop=0; private ListBox loopTime; private ListBox speedBox; private long remainTime; private CheckBox abLoopCheck; private TabLayoutPanel toolsPanel; private HorizontalPanel screenshotContainer; @Override protected void beforeUpdate(WebGLRenderer renderer) { //camera.getPosition().incrementX((mouseX - camera.getPosition().getX() ) * 0.05); //camera.getPosition().incrementY((-mouseY - camera.getPosition().getY() ) * 0.05); //validate ab-check boolean abLoop=abLoopCheck.getValue(); if(abLoop && bvh!=null){ if(aFrame>=bFrame){ abLoopCheck.setValue(false); } if(aFrame>bvh.getFrames()-1 || bFrame>bvh.getFrames()-1){ abLoopCheck.setValue(false); } } Object3DUtils.setVisibleAll(backgroundContainer, drawBackground.getValue()); //backgroundContainer.setVisible(); boneContainer.setPosition(positionXRange.getValue(), positionYRange.getValue(), positionZRange.getValue()); if(rootGroup!=null){ String lastOrder=rootGroup.getRotation().getOrder(); rootGroup.getRotation().set(Math.toRadians(rotationRange.getValue()),Math.toRadians(rotationYRange.getValue()),Math.toRadians(rotationZRange.getValue()),lastOrder); } if(bvh!=null){ if(playing){ long last=clock.delta()+remainTime; double ftime=(bvh.getFrameTime()*1000/playSpeed); if(ftime==0){ return; //somehow frame become strange } int frame=(int) (last/ftime); remainTime=(long) (last-(ftime*frame)); // log(""+frame); //GWT.log(ftime+","+frame+","+remainTime); int minFrame=0; int maxFrame=bvh.getFrames(); if(abLoop){ minFrame=aFrame; maxFrame=bFrame; } if(frame>0){ int index=currentFrameRange.getValue()+frame; boolean overLoop=index>=maxFrame; index=(index-minFrame)%(maxFrame-minFrame); index+=minFrame; if(ignoreFirst.getValue() && index==0 &&minFrame==0){ index=1; } updatePoseIndex(index); if(overLoop && bvhFileList.size()>1 && !abLoop){ //next Frame try{ int maxLoop=Integer.parseInt(loopTime.getItemText(loopTime.getSelectedIndex())); //log("maxloop:"+maxLoop); if(maxLoop>0){ currentLoop++; if(currentLoop>=maxLoop){ currentLoop=0; doNextMotion(); } } }catch(Exception e){} } } /* double delta=(double)(System.currentTimeMillis()-ctime)/1000; delta%=bvh.getMotion().getDuration(); poseIndex = (int) (delta/bvh.getMotion().getFrameTime()); */ } } if(reserveScreenShot){//get renderer before clear; doScreenshot(); reserveScreenShot=false; } } private void doScreenshot(){ screenshotContainer.clear(); canvas.getRenderer().render(scene, camera);//do render here String url=canvas.getRenderer().gwtPngDataUrl(); Anchor anchor=HTML5Download.get().generateBase64DownloadLink(url, "image/png", "screenshot.png", "download", true); screenshotContainer.add(anchor); } public void addBVHData(BVHDataContainer dataContainer){ if(!existsBVHData(dataContainer)){ bvhFileList.add(dataContainer); } dataListCell.setDatas(bvhFileList); dataListCell.setSelection(dataContainer); tabPanel.selectTab(0); } public void addBVHDatas(List<BVHDataContainer> dataContainers){ for(BVHDataContainer dataContainer:dataContainers){ if(!existsBVHData(dataContainer)){ bvhFileList.add(dataContainer); } } dataListCell.setDatas(bvhFileList); dataListCell.setSelection(dataContainers.get(0)); tabPanel.selectTab(0); } private boolean existsBVHData(BVHDataContainer dataContainer){ for(BVHDataContainer container:bvhFileList){ if(container.getName().equals(dataContainer.getName())){ return true; } } return false; } @Override public void resized(int width, int height) { super.resized(width, height); leftBottom(bottomPanel); } @Override public String getHtml(){ return "BVH Motion Creator ver."+version+"<br/>"+super.getHtml()+". Sample BVH File from <a href='https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture/cmu-bvh-conversion'>CMU Graphics Lab Motion Capture Database.</a><br/> More Infomation click <a href='https://github.com/akjava/BVH-Motion-Creator'>https://github.com/akjava/BVH-Motion-Creator</a>"; } @Override public String getTabTitle() { return "BVH Player"; } @Override public void onDoubleClick(DoubleClickEvent event) { // TODO Auto-generated method stub } }